//
//  DMAdConfig.m
//  DualMediationSDK
//
//  广告配置实现
//

#import "DMAdConfig.h"
#import "../Models/DMUserConsent.h"

@implementation DMAdRequest

- (instancetype)initWithAdType:(DMAdType)adType adUnitId:(NSString *)adUnitId {
    self = [super init];
    if (self) {
        _adType = adType;
        _adUnitId = adUnitId;
        _testMode = NO;
    }
    return self;
}

@end

@implementation DMSDKConfiguration

- (instancetype)initWithAppId:(NSString *)appId enabledPlatforms:(NSArray<NSString *> *)enabledPlatforms {
    self = [super init];
    if (self) {
        self.appID = appId;
        self.enableDebugMode = NO;
        // enabledPlatforms 属性在头文件中没有定义，跳过此赋值
    }
    return self;
}

+ (instancetype)defaultConfiguration {
    DMSDKConfiguration *config = [[DMSDKConfiguration alloc] init];
    config.enableDebugMode = NO;
    config.enableLogging = YES;
    config.logLevel = DMLogLevelInfo;
    config.requestTimeout = 30.0;
    config.maxRetryCount = 3;
    config.enablePersonalizedAds = YES;
    config.enableTestMode = NO;
    config.enableATTCheck = YES;
    config.enableGDPRCheck = YES;
    config.enableCCPACheck = YES;
    config.cacheTimeout = 3600.0; // 1小时
    config.maxCacheSize = 100;
    config.configRefreshInterval = 86400.0; // 24小时
    return config;
}

+ (instancetype)debugConfiguration {
    DMSDKConfiguration *config = [self defaultConfiguration];
    config.enableDebugMode = YES;
    config.enableLogging = YES;
    config.logLevel = DMLogLevelVerbose;
    config.enableTestMode = YES;
    return config;
}

@end

@implementation DMAdConfig

static DMAdConfig *_sharedConfig = nil;
static dispatch_once_t _onceToken;

+ (instancetype)sharedConfig {
    dispatch_once(&_onceToken, ^{
        _sharedConfig = [[DMAdConfig alloc] init];
    });
    return _sharedConfig;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        [self setupDefaultConfig];
    }
    return self;
}

- (instancetype)initWithAppId:(NSString *)appId {
    self = [super init];
    if (self) {
        [self setupDefaultConfig];
        _appId = appId;
    }
    return self;
}

- (void)setupDefaultConfig {
    _sdkVersion = @"1.0.0";
    _testMode = NO;
    _gdprEnabled = YES;
    _ccpaEnabled = YES;
    _coppaEnabled = NO;
    
    // EU隐私设置
    _isShowEUPrivacy = @"0";  // 默认不显示
    
    // 调试模式
    _isDebugMode = NO;
    
    // 默认用户位置
    _userProvince = nil;
    
    // 设置默认值
    _enabledPlatforms = @[@"IronSource", @"AppLovin"];
    _platformConfigs = @{};
    _adUnitIds = @{};
    _testDeviceIds = @[];
    
    // SDK信息
    _appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] ?: @"DualMediationApp";
}

@end

@implementation DMABTestConfig
@end

@implementation DMStrategyConfig
@end

@implementation DMComplianceStatus

- (instancetype)init {
    self = [super init];
    if (self) {
        self.attStatus = 0;
        self.gdprApplies = NO;
        self.gdprConsent = NO;
        self.ccpaApplies = NO;
        self.ccpaOptOut = NO;
        self.region = @"US";
    }
    return self;
}

@end

@implementation DMComplianceResult

- (instancetype)init {
    self = [super init];
    if (self) {
        self.isCompliant = NO;
        self.complianceStatus = [[DMComplianceStatus alloc] init];
        self.userConsent = nil;
        self.error = nil;
    }
    return self;
}

@end


@implementation DMUserConsent

@synthesize createdAt = _createdAt;
@synthesize updatedAt = _updatedAt;
@synthesize version = _version;
@synthesize consentHistory = _consentHistory;

- (instancetype)init {
    self = [super init];
    if (self) {
        // 设置默认值
        _createdAt = [NSDate date];
        _updatedAt = [NSDate date];
        _version = @"1.0.0";
        _consentHistory = @[];
        
        self.attStatus = 0; // DMATTStatusNotRequired
        self.gdprStatus = DMConsentStatusUnknown;
        self.ccpaStatus = DMConsentStatusUnknown;
        self.umpStatus = DMConsentStatusUnknown;
        self.coppaStatus = DMConsentStatusUnknown;
        
        self.gdprApplies = NO;
        self.gdprConsentString = nil;
        self.gdprConsentDate = nil;
        self.ccpaApplies = NO;
        self.ccpaOptOutDate = nil;
        self.canCollectData = YES;
        self.canShowPersonalizedAds = YES;
        self.canShareData = YES;
        self.canCollectAnalytics = YES;
        self.canTrackAcrossApps = NO;
        
        self.countryCode = nil;
        self.stateCode = nil;
        self.isInGDPRRegion = NO;
        self.isInCCPARegion = NO;
        self.userAge = nil;
        self.isChildUser = NO;
        self.requiresParentalConsent = NO;
    }
    return self;
}

#pragma mark - NSCopying

- (id)copyWithZone:(NSZone *)zone {
    DMUserConsent *copy = [[DMUserConsent alloc] init];
    
    // 复制基本属性
    copy.userId = [self.userId copy];
    copy->_createdAt = [self.createdAt copy];
    copy->_updatedAt = [self.updatedAt copy];
    copy->_version = [self.version copy];
    
    // 复制同意状态
    copy.gdprStatus = self.gdprStatus;
    copy.ccpaStatus = self.ccpaStatus;
    copy.umpStatus = self.umpStatus;
    copy.coppaStatus = self.coppaStatus;
    
    // 复制详细同意信息
    copy.canCollectData = self.canCollectData;
    copy.canShowPersonalizedAds = self.canShowPersonalizedAds;
    copy.canShareData = self.canShareData;
    copy.canCollectAnalytics = self.canCollectAnalytics;
    copy.canTrackAcrossApps = self.canTrackAcrossApps;
    
    // 复制GDPR属性
    copy.gdprApplies = self.gdprApplies;
    copy.gdprConsentString = [self.gdprConsentString copy];
    copy.gdprConsentDate = [self.gdprConsentDate copy];
    
    // 复制CCPA属性
    copy.ccpaApplies = self.ccpaApplies;
    copy.ccpaOptOutDate = [self.ccpaOptOutDate copy];
    
    // 复制地理信息
    copy.countryCode = [self.countryCode copy];
    copy.stateCode = [self.stateCode copy];
    copy.isInGDPRRegion = self.isInGDPRRegion;
    copy.isInCCPARegion = self.isInCCPARegion;
    
    // 复制用户年龄信息
    copy.userAge = [self.userAge copy];
    copy.isChildUser = self.isChildUser;
    copy.requiresParentalConsent = self.requiresParentalConsent;
    
    // 复制同意历史
    copy->_consentHistory = [self.consentHistory copy];
    
    return copy;
}

#pragma mark - NSCoding

+ (BOOL)supportsSecureCoding {
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.userId forKey:@"userId"];
    [coder encodeObject:self.createdAt forKey:@"createdAt"];
    [coder encodeObject:self.updatedAt forKey:@"updatedAt"];
    [coder encodeObject:self.version forKey:@"version"];
    
    [coder encodeInteger:self.gdprStatus forKey:@"gdprStatus"];
    [coder encodeInteger:self.ccpaStatus forKey:@"ccpaStatus"];
    [coder encodeInteger:self.umpStatus forKey:@"umpStatus"];
    [coder encodeInteger:self.coppaStatus forKey:@"coppaStatus"];
    
    [coder encodeBool:self.canCollectData forKey:@"canCollectData"];
    [coder encodeBool:self.canShowPersonalizedAds forKey:@"canShowPersonalizedAds"];
    [coder encodeBool:self.canShareData forKey:@"canShareData"];
    [coder encodeBool:self.canCollectAnalytics forKey:@"canCollectAnalytics"];
    [coder encodeBool:self.canTrackAcrossApps forKey:@"canTrackAcrossApps"];
    
    [coder encodeBool:self.gdprApplies forKey:@"gdprApplies"];
    [coder encodeObject:self.gdprConsentString forKey:@"gdprConsentString"];
    [coder encodeObject:self.gdprConsentDate forKey:@"gdprConsentDate"];
    
    [coder encodeBool:self.ccpaApplies forKey:@"ccpaApplies"];
    [coder encodeObject:self.ccpaOptOutDate forKey:@"ccpaOptOutDate"];
    
    [coder encodeObject:self.countryCode forKey:@"countryCode"];
    [coder encodeObject:self.stateCode forKey:@"stateCode"];
    [coder encodeBool:self.isInGDPRRegion forKey:@"isInGDPRRegion"];
    [coder encodeBool:self.isInCCPARegion forKey:@"isInCCPARegion"];
    
    [coder encodeObject:self.userAge forKey:@"userAge"];
    [coder encodeBool:self.isChildUser forKey:@"isChildUser"];
    [coder encodeBool:self.requiresParentalConsent forKey:@"requiresParentalConsent"];
    
    [coder encodeObject:self.consentHistory forKey:@"consentHistory"];
}

+ (nullable instancetype)fromDictionary:(NSDictionary *)dictionary {
    if (!dictionary) return nil;
    
    DMUserConsent *consent = [[DMUserConsent alloc] init];
    consent.userId = dictionary[@"userId"];
    // Skip readonly properties: createdAt, updatedAt, version, consentHistory
    consent.gdprStatus = [dictionary[@"gdprStatus"] integerValue];
    consent.ccpaStatus = [dictionary[@"ccpaStatus"] integerValue];
    consent.umpStatus = [dictionary[@"umpStatus"] integerValue];
    consent.coppaStatus = [dictionary[@"coppaStatus"] integerValue];
    consent.canCollectData = [dictionary[@"canCollectData"] boolValue];
    consent.canShowPersonalizedAds = [dictionary[@"canShowPersonalizedAds"] boolValue];
    consent.canShareData = [dictionary[@"canShareData"] boolValue];
    consent.canCollectAnalytics = [dictionary[@"canCollectAnalytics"] boolValue];
    consent.canTrackAcrossApps = [dictionary[@"canTrackAcrossApps"] boolValue];
    consent.gdprApplies = [dictionary[@"gdprApplies"] boolValue];
    consent.gdprConsentString = dictionary[@"gdprConsentString"];
    consent.gdprConsentDate = dictionary[@"gdprConsentDate"];
    consent.ccpaApplies = [dictionary[@"ccpaApplies"] boolValue];
    consent.ccpaOptOutDate = dictionary[@"ccpaOptOutDate"];
    consent.countryCode = dictionary[@"countryCode"];
    consent.stateCode = dictionary[@"stateCode"];
    consent.isInGDPRRegion = [dictionary[@"isInGDPRRegion"] boolValue];
    consent.isInCCPARegion = [dictionary[@"isInCCPARegion"] boolValue];
    consent.userAge = dictionary[@"userAge"]; // Keep as NSNumber
    consent.isChildUser = [dictionary[@"isChildUser"] boolValue];
    consent.requiresParentalConsent = [dictionary[@"requiresParentalConsent"] boolValue];
    // Skip readonly property: consentHistory
    
    return consent;
}

+ (nullable instancetype)fromJSONString:(NSString *)jsonString {
    if (!jsonString) return nil;
    
    NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
    
    if (error || ![dictionary isKindOfClass:[NSDictionary class]]) {
        return nil;
    }
    
    return [self fromDictionary:dictionary];
}

+ (NSString *)stringForConsentType:(DMConsentType)type {
    switch (type) {
        case DMConsentTypeGDPR: return @"GDPR";
        case DMConsentTypeCCPA: return @"CCPA";
        case DMConsentTypeCOPPA: return @"COPPA";
        case DMConsentTypeATT: return @"ATT";
        case DMConsentTypeUMP: return @"UMP";
        default: return @"Unknown";
    }
}

+ (NSString *)stringForConsentStatus:(DMConsentStatus)status {
    switch (status) {
        case DMConsentStatusUnknown: return @"Unknown";
        case DMConsentStatusGranted: return @"Granted";
        case DMConsentStatusDenied: return @"Denied";
        case DMConsentStatusNotRequired: return @"NotRequired";
        default: return @"Unknown";
    }
}

+ (DMConsentType)consentTypeForString:(NSString *)string {
    if ([string isEqualToString:@"GDPR"]) return DMConsentTypeGDPR;
    if ([string isEqualToString:@"CCPA"]) return DMConsentTypeCCPA;
    if ([string isEqualToString:@"COPPA"]) return DMConsentTypeCOPPA;
    if ([string isEqualToString:@"ATT"]) return DMConsentTypeATT;
    if ([string isEqualToString:@"UMP"]) return DMConsentTypeUMP;
    return DMConsentTypeGDPR; // default
}

+ (DMConsentStatus)consentStatusForString:(NSString *)string {
    if ([string isEqualToString:@"Granted"]) return DMConsentStatusGranted;
    if ([string isEqualToString:@"Denied"]) return DMConsentStatusDenied;
    if ([string isEqualToString:@"NotRequired"]) return DMConsentStatusNotRequired;
    return DMConsentStatusUnknown; // default
}

+ (instancetype)defaultConsent {
    return [[DMUserConsent alloc] init];
}

+ (instancetype)consentForCountry:(NSString *)countryCode state:(nullable NSString *)stateCode {
    DMUserConsent *consent = [[DMUserConsent alloc] init];
    consent.countryCode = countryCode;
    consent.stateCode = stateCode;
    consent.isInGDPRRegion = [self isGDPRApplicableForCountry:countryCode];
    consent.isInCCPARegion = [self isCCPAApplicableForCountry:countryCode state:stateCode];
    return consent;
}

- (void)setConsentStatus:(DMConsentStatus)status forType:(DMConsentType)type {
    switch (type) {
        case DMConsentTypeGDPR:
            self.gdprStatus = status;
            break;
        case DMConsentTypeCCPA:
            self.ccpaStatus = status;
            break;
        case DMConsentTypeCOPPA:
            self.coppaStatus = status;
            break;
        case DMConsentTypeUMP:
            self.umpStatus = status;
            break;
        case DMConsentTypeATT:
            // ATT现在由DMATTManager独立管理
            break;
    }
}

- (DMConsentStatus)getConsentStatusForType:(DMConsentType)type {
    switch (type) {
        case DMConsentTypeGDPR:
            return self.gdprStatus;
        case DMConsentTypeCCPA:
            return self.ccpaStatus;
        case DMConsentTypeCOPPA:
            return self.coppaStatus;
        case DMConsentTypeUMP:
            return self.umpStatus;
        case DMConsentTypeATT:
            // ATT现在由DMATTManager独立管理
            return DMConsentStatusUnknown;
        default:
            return DMConsentStatusUnknown;
    }
}

- (BOOL)hasRequiredConsents {
    if (self.isInGDPRRegion && self.gdprStatus != DMConsentStatusGranted) {
        return NO;
    }
    if (self.isInCCPARegion && self.ccpaStatus == DMConsentStatusUnknown) {
        return NO;
    }
    return YES;
}

- (BOOL)canShowAds {
    return [self hasRequiredConsents];
}

- (BOOL)canShowPersonalizedAds {
    // Avoid recursive getter call; return backing ivar
    return _canShowPersonalizedAds;
}

- (BOOL)canCollectUserData {
    return self.canCollectData;
}

- (BOOL)isValid {
    return self.userId != nil && self.createdAt != nil;
}

- (nullable NSArray<NSString *> *)getValidationErrors {
    NSMutableArray *errors = [NSMutableArray array];
    if (!self.userId) {
        [errors addObject:@"User ID is required"];
    }
    if (!self.createdAt) {
        [errors addObject:@"Created date is required"];
    }
    return errors.count > 0 ? [errors copy] : nil;
}

- (BOOL)saveToLocalStorage {
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self requiringSecureCoding:YES error:nil];
    if (data) {
        [[NSUserDefaults standardUserDefaults] setObject:data forKey:@"DMUserConsent"];
        return YES;
    }
    return NO;
}

+ (nullable instancetype)loadFromLocalStorage {
    NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"DMUserConsent"];
    if (data) {
        return [NSKeyedUnarchiver unarchivedObjectOfClass:[DMUserConsent class] fromData:data error:nil];
    }
    return nil;
}

+ (void)clearLocalStorage {
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"DMUserConsent"];
}

- (NSDictionary *)toDictionary {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    if (self.userId) dict[@"userId"] = self.userId;
    if (self.createdAt) dict[@"createdAt"] = self.createdAt;
    if (self.updatedAt) dict[@"updatedAt"] = self.updatedAt;
    if (self.version) dict[@"version"] = self.version;
    dict[@"gdprStatus"] = @(self.gdprStatus);
    dict[@"ccpaStatus"] = @(self.ccpaStatus);
    dict[@"umpStatus"] = @(self.umpStatus);
    dict[@"coppaStatus"] = @(self.coppaStatus);
    dict[@"canCollectData"] = @(self.canCollectData);
    dict[@"canShowPersonalizedAds"] = @(self.canShowPersonalizedAds);
    dict[@"canShareData"] = @(self.canShareData);
    dict[@"canCollectAnalytics"] = @(self.canCollectAnalytics);
    dict[@"canTrackAcrossApps"] = @(self.canTrackAcrossApps);
    dict[@"gdprApplies"] = @(self.gdprApplies);
    if (self.gdprConsentString) dict[@"gdprConsentString"] = self.gdprConsentString;
    if (self.gdprConsentDate) dict[@"gdprConsentDate"] = self.gdprConsentDate;
    dict[@"ccpaApplies"] = @(self.ccpaApplies);
    if (self.ccpaOptOutDate) dict[@"ccpaOptOutDate"] = self.ccpaOptOutDate;
    if (self.countryCode) dict[@"countryCode"] = self.countryCode;
    if (self.stateCode) dict[@"stateCode"] = self.stateCode;
    dict[@"isInGDPRRegion"] = @(self.isInGDPRRegion);
    dict[@"isInCCPARegion"] = @(self.isInCCPARegion);
    if (self.userAge) dict[@"userAge"] = self.userAge;
    dict[@"isChildUser"] = @(self.isChildUser);
    dict[@"requiresParentalConsent"] = @(self.requiresParentalConsent);
    if (self.consentHistory) dict[@"consentHistory"] = self.consentHistory;
    return [dict copy];
}

- (nullable NSString *)toJSONString {
    NSDictionary *dict = [self toDictionary];
    NSError *error;
    NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
    if (error) return nil;
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

+ (BOOL)isGDPRApplicableForCountry:(NSString *)countryCode {
    NSArray *gdprCountries = @[@"AT", @"BE", @"BG", @"HR", @"CY", @"CZ", @"DK", @"EE", @"FI", @"FR", @"DE", @"GR", @"HU", @"IE", @"IT", @"LV", @"LT", @"LU", @"MT", @"NL", @"PL", @"PT", @"RO", @"SK", @"SI", @"ES", @"SE", @"GB", @"IS", @"LI", @"NO"];
    return [gdprCountries containsObject:[countryCode uppercaseString]];
}

+ (BOOL)isCCPAApplicableForCountry:(NSString *)countryCode state:(nullable NSString *)stateCode {
    return [countryCode.uppercaseString isEqualToString:@"US"] && [stateCode.uppercaseString isEqualToString:@"CA"];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        self.userId = [coder decodeObjectOfClass:[NSString class] forKey:@"userId"];
        _createdAt = [coder decodeObjectOfClass:[NSDate class] forKey:@"createdAt"];
        _updatedAt = [coder decodeObjectOfClass:[NSDate class] forKey:@"updatedAt"];
        _version = [coder decodeObjectOfClass:[NSString class] forKey:@"version"];
        
        self.gdprStatus = [coder decodeIntegerForKey:@"gdprStatus"];
        self.ccpaStatus = [coder decodeIntegerForKey:@"ccpaStatus"];
        self.umpStatus = [coder decodeIntegerForKey:@"umpStatus"];
        self.coppaStatus = [coder decodeIntegerForKey:@"coppaStatus"];
        
        self.canCollectData = [coder decodeBoolForKey:@"canCollectData"];
        self.canShowPersonalizedAds = [coder decodeBoolForKey:@"canShowPersonalizedAds"];
        self.canShareData = [coder decodeBoolForKey:@"canShareData"];
        self.canCollectAnalytics = [coder decodeBoolForKey:@"canCollectAnalytics"];
        self.canTrackAcrossApps = [coder decodeBoolForKey:@"canTrackAcrossApps"];
        
        self.gdprApplies = [coder decodeBoolForKey:@"gdprApplies"];
        self.gdprConsentString = [coder decodeObjectOfClass:[NSString class] forKey:@"gdprConsentString"];
        self.gdprConsentDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"gdprConsentDate"];
        
        self.ccpaApplies = [coder decodeBoolForKey:@"ccpaApplies"];
        self.ccpaOptOutDate = [coder decodeObjectOfClass:[NSDate class] forKey:@"ccpaOptOutDate"];
        
        self.countryCode = [coder decodeObjectOfClass:[NSString class] forKey:@"countryCode"];
        self.stateCode = [coder decodeObjectOfClass:[NSString class] forKey:@"stateCode"];
        self.isInGDPRRegion = [coder decodeBoolForKey:@"isInGDPRRegion"];
        self.isInCCPARegion = [coder decodeBoolForKey:@"isInCCPARegion"];
        
        self.userAge = [coder decodeObjectOfClass:[NSNumber class] forKey:@"userAge"];
        self.isChildUser = [coder decodeBoolForKey:@"isChildUser"];
        self.requiresParentalConsent = [coder decodeBoolForKey:@"requiresParentalConsent"];
        
        _consentHistory = [coder decodeObjectOfClasses:[NSSet setWithObjects:[NSArray class], [NSDictionary class], [NSString class], [NSNumber class], [NSDate class], nil] forKey:@"consentHistory"];
    }
    return self;
}

@end

@implementation DMSDKStatus

- (instancetype)init {
    self = [super init];
    if (self) {
        _isInitialized = NO;
        _enabledPlatforms = @[];
        _version = @"1.0.0";
        _complianceStatus = nil;
    }
    return self;
}

@end

@implementation DMAdResponse

- (instancetype)initWithPlatform:(NSString *)platform adUnitId:(NSString *)adUnitId {
    self = [super init];
    if (self) {
        _platform = platform;
        _adUnitId = adUnitId;
        _eCPM = 0.0;
        _success = NO;
        _error = nil;
        _adData = nil;
        _responseTime = 0.0;
    }
    return self;
}

@end
